package org.summer.gateway.security;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.summer.common.http.Result;
import org.summer.common.http.ResultCode;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.summer.gateway.cache.LoginUserCacheHandler;
import org.summer.gateway.dto.LoginSuccess;
import org.summer.gateway.handler.ServerResponseHandler;
import org.summer.gateway.jwt.JsonWebToken;
import org.summer.gateway.jwt.JsonWebTokenResolver;
import org.summer.gateway.pojo.LoginUser;
import org.summer.gateway.pojo.SecurityUser;
import reactor.core.publisher.Mono;

@Log4j2
@Component
@RequiredArgsConstructor
public class LoginSuccessHandler implements ServerAuthenticationSuccessHandler {
    private final ServerResponseHandler responseHandler;
    private final LoginUserCacheHandler cacheHandler;
    private final JsonWebTokenResolver<JsonWebToken> jwtResolver;
    @Override
    public Mono<Void> onAuthenticationSuccess(WebFilterExchange webFilterExchange, Authentication authentication) {
        log.debug("用户登录成功: {}", authentication.getName());
        JsonWebToken token = createToken(authentication.getName());
        if (token.isError()){
            log.error("创建用户令牌时出现错误: {}",token.getErrorMessage());
            Result<String> result = Result.build(ResultCode.LOGIN_FAILURE_JWT_CREATE_ERROR, "用户登录成功,但无法构建用户登录数据,创建用户jwt令牌出现错误: " + token.getErrorMessage(), false);
            return this.responseHandler.handlerResponse(webFilterExchange.getExchange(), result, HttpStatus.OK);
        }
        // 获取当前登录的用户信息
        SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
        // 设置用户登录后缓存的用户用户信息
        LoginUser loginUser = buildLoginUser(securityUser, token);
        // 设置用户登录成功后返回前端的数据
        LoginSuccess loginSuccess = buildLoginSuccess(securityUser,token);
        // 缓存用户登录信息,然后响应前端数据
        return cacheHandler.set(securityUser.getUsername(), loginUser)
                .then(this.responseHandler.handlerResponse(webFilterExchange.getExchange(), Result.ok(ResultCode.LOGIN_SUCCESS, loginSuccess), HttpStatus.OK));
    }

    /**
     * 侯建用户登录成功后返回前端的数据
     */
    private LoginSuccess buildLoginSuccess(SecurityUser securityUser, JsonWebToken token) {
        LoginSuccess loginSuccess = new LoginSuccess();
        loginSuccess.setId(securityUser.getId());
        loginSuccess.setUsername(securityUser.getUsername());
        loginSuccess.setTokenId(token.getTokenId());
        loginSuccess.setToken(token.getToken());
        loginSuccess.setAvatar(securityUser.getAvatar());
        loginSuccess.setIdentity(securityUser.getIdentity());
        loginSuccess.setLoginTime(token.getCreateTime());
        loginSuccess.setExpireTime(token.getExpireTime());
        loginSuccess.setExpireSeconds(token.getExpireSeconds());
        return loginSuccess;
    }

    /**
     * 构建用户登录信息缓存对象
     */
    private LoginUser buildLoginUser(SecurityUser securityUser, JsonWebToken token) {
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(securityUser.getId());
        loginUser.setUsername(securityUser.getUsername());
        loginUser.setAuthorities(securityUser.getAuthorities());
        loginUser.setTokenId(token.getTokenId());
        return loginUser;
    }

    /**
     * 创建jwt令牌
     */
    private JsonWebToken createToken(String username) {
        JsonWebToken jsonWebToken = new JsonWebToken();
        jsonWebToken.setUsername(username);
        return jwtResolver.createToken(jsonWebToken);
    }
}
